package edu.lambdateacher.expressions;

/*
 LambdaTeacher
 Copyright (C) 2000  Kim Mason
 Copyright (C) 2014  Vitalij Zadneprovskij

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

import java.util.HashSet;

/**
 * The class Variable represents a Lamdba variable. It is a subclass of
 * Expression. If a name_sub or any reduction occurs, parentmodified is set to
 * true.
 */
public class Variable extends Expression implements Cloneable {
	private String varname;

	/**
	 * A simple constructor.
	 */
	public Variable(String inname) {
		super();
		this.setVarName(inname);
	}

	public String getVarName() {
		return varname;
	}

	public void setVarName(String inname) {
		this.varname = inname;
	}

	/**
	 * containsUnbound returns true if the variable name matches the inname.
	 */
	public boolean containsUnbound(String inname) {
		if (inname == null)
			return false;

		if (!(inname.equals(getVarName())))
			return false;

		return true;
	}

	/**
	 * Override the clone method in superclass object
	 */
	public Object clone() {
		String thename = new String(this.getVarName());
		Variable toreturn = (Variable) super.clone();
		toreturn.setVarName(thename);
		return toreturn;
	}

	/**
	 * unParse simply unParses this variables name.
	 */
	public String stringRepresentation(boolean verbose) {
		if (this.getVarName() == null)
			return "";
		return new String(getVarName() + " ");
	}

	/**
	 * name_substitute returns a clone of param if this variables name matches
	 * inname. Parentmodified is set to true, as upper bindings should be
	 * destroyed.
	 */
	public Expression nameSubstitute(String inname, Expression param) {
		if (this.getVarName() == null)
			return this;

		// we don't have a match, so return this.
		if (this.getVarName().equals(inname) == false)
			return this;

		Expression toreturn = (Expression) param.clone();
		toreturn.setParentModified(true);
		return toreturn;
	}

	/**
	 * findUnboundVars returns a HashSet with the names of all of the unbound
	 * variables in the current expression. The input HashSet (bound_vars)
	 * contains all of the variable names that are bound.
	 */
	public HashSet findUnboundVars(HashSet bound_vars) {
		HashSet toreturn = new HashSet();

		// is the current variable bound? If yes, return an empty
		// Hashset.
		if (bound_vars.contains(this.getVarName()))
			return toreturn;

		// otherwise, put the current varname in toreturn
		toreturn.add(new String(this.getVarName()));

		return toreturn;
	}



}
